package com.william.jdbcplus.core.dialect.ddl.util;

import com.william.jdbcplus.common.enums.DbType;
import com.william.jdbcplus.core.dialect.ddl.pk.IPk;
import com.william.jdbcplus.core.dialect.ddl.pk.PkFactory;
import com.william.jdbcplus.core.dialect.ddl.util.model.TableMeta;
import com.william.jdbcplus.core.meta.TableInfo;
import com.william.jdbcplus.core.meta.TablePkInfo;
import com.william.jdbcplus.core.util.JdbcExecUtil;
import com.william.jdbcplus.core.util.datameta.TableMetaPkInfo;

import javax.sql.DataSource;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 主键处理
 *
 * @author niliwei
 */
public class PkUtil {
    /**
     * 检查主键是否一致
     *
     * @param dbType    数据库类型
     * @param tableMeta 表信息
     * @return
     */
    public static List<String> check(DbType dbType, TableMeta tableMeta) {
        List<String> errList = new LinkedList<>();
        List<TableMetaPkInfo> pkList = tableMeta.getTableMeta().getPkList();
        Map<String, TableMetaPkInfo> pkInfoMap = pkList.stream().collect(Collectors.toMap(e -> e.getColumnName().toLowerCase(), e -> e));
        TableInfo tableInfo = tableMeta.getTableInfo();
        List<TablePkInfo> pkInfoList = tableInfo.getPkList();
        IPk iPk = PkFactory.getInstance(dbType);
        for (TablePkInfo pkInfo : pkInfoList) {
            if (pkInfoMap.containsKey(pkInfo.getPkColumn().toLowerCase())) {
                TableMetaPkInfo metaPkInfo = pkInfoMap.get(pkInfo.getPkColumn().toLowerCase());
                // 数据表中主键已经存在
                if (!iPk.match(tableMeta.getClazz(), pkInfo, metaPkInfo)) {
                    errList.add("表 " + tableMeta.getTableInfo().getTableName() + " 主键对应列不正确");
                }
            } else {
                // 数据表中主键不存在，则新增主键
                errList.add("表 " + tableMeta.getTableInfo().getTableName() + " 主键不存在");
            }
        }

        return errList;
    }

    /**
     * 更新主键结构
     *
     * @param dbType    数据库类型
     * @param tableMeta 实体表结构信息
     * @param ds        数据源
     * @return
     */
    public static void update(DbType dbType, TableMeta tableMeta, DataSource ds) {
        List<TableMetaPkInfo> pkList = tableMeta.getTableMeta().getPkList();
        Map<String, TableMetaPkInfo> pkInfoMap = pkList.stream().collect(Collectors.toMap(e -> e.getColumnName().toLowerCase(), e -> e));
        TableInfo tableInfo = tableMeta.getTableInfo();
        List<TablePkInfo> pkInfoList = tableInfo.getPkList();
        IPk iPk = PkFactory.getInstance(dbType);
        for (TablePkInfo pkInfo : pkInfoList) {
            if (pkInfoMap.containsKey(pkInfo.getPkColumn().toLowerCase())) {
                TableMetaPkInfo metaPkInfo = pkInfoMap.get(pkInfo.getPkColumn().toLowerCase());
                // 数据表中主键已经存在，则修改
                if (!iPk.match(tableMeta.getClazz(), pkInfo, metaPkInfo)) {
                    String sql = iPk.modify(tableMeta.getClazz(), pkInfo);
                    JdbcExecUtil.execOne(sql, ds);
                }
            } else {
                // 数据表中主键不存在，则新增主键
                String sql = iPk.add(tableMeta.getClazz(), pkInfo);
                JdbcExecUtil.execOne(sql, ds);
            }
        }
    }

    /**
     * 获取更新主键结构脚本
     *
     * @param dbType
     * @param tableMeta
     */
    public static List<String> getUpdateSQL(DbType dbType, TableMeta tableMeta) {
        List<String> sqlList = new LinkedList<>();
        List<TableMetaPkInfo> pkList = tableMeta.getTableMeta().getPkList();
        Map<String, TableMetaPkInfo> pkInfoMap = pkList.stream().collect(Collectors.toMap(e -> e.getColumnName().toLowerCase(), e -> e));
        TableInfo tableInfo = tableMeta.getTableInfo();
        List<TablePkInfo> pkInfoList = tableInfo.getPkList();
        IPk iPk = PkFactory.getInstance(dbType);
        for (TablePkInfo pkInfo : pkInfoList) {
            if (pkInfoMap.containsKey(pkInfo.getPkColumn().toLowerCase())) {
                TableMetaPkInfo metaPkInfo = pkInfoMap.get(pkInfo.getPkColumn().toLowerCase());
                // 数据表中主键已经存在，则修改
                if (!iPk.match(tableMeta.getClazz(), pkInfo, metaPkInfo)) {
                    String sql = iPk.modify(tableMeta.getClazz(), pkInfo);
                    sqlList.add(sql);
                }
            } else {
                // 数据表中主键不存在，则新增主键
                String sql = iPk.add(tableMeta.getClazz(), pkInfo);
                sqlList.add(sql);
            }
        }

        return sqlList;
    }
}
